home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / programming / other / python-1.52 / demo / scripts / ftpstats.py < prev    next >
Text File  |  1999-06-14  |  4KB  |  145 lines

  1. #! /usr/bin/env python
  2.  
  3. # Extract statistics from ftp daemon log.
  4.  
  5. # Usage:
  6. # ftpstats [-m maxitems] [-s search] [file]
  7. # -m maxitems: restrict number of items in "top-N" lists, default 25.
  8. # -s string:   restrict statistics to lines containing this string.
  9. # Default file is /usr/adm/ftpd;  a "-" means read stdandard input.
  10.  
  11. # The script must be run on the host where the ftp daemon runs.
  12. # (At CWI this is currently buizerd.)
  13.  
  14. import os
  15. import sys
  16. import regex
  17. import string
  18. import getopt
  19.  
  20. pat = '^\([a-zA-Z0-9 :]*\)!\(.*\)!\(.*\)!\([<>].*\)!\([0-9]+\)!\([0-9]+\)$'
  21. prog = regex.compile(pat)
  22.  
  23. def main():
  24.     maxitems = 25
  25.     search = None
  26.     try:
  27.         opts, args = getopt.getopt(sys.argv[1:], 'm:s:')
  28.     except getopt.error, msg:
  29.         print msg
  30.         print 'usage: ftpstats [-m maxitems] [file]'
  31.         sys.exit(2)
  32.     for o, a in opts:
  33.         if o == '-m':
  34.             maxitems = string.atoi(a)
  35.         if o == '-s':
  36.             search = a
  37.     file = '/usr/adm/ftpd'
  38.     if args: file = args[0]
  39.     if file == '-':
  40.         f = sys.stdin
  41.     else:
  42.         try:
  43.             f = open(file, 'r')
  44.         except IOError, msg:
  45.             print file, ':', msg
  46.             sys.exit(1)
  47.     bydate = {}
  48.     bytime = {}
  49.     byfile = {}
  50.     bydir = {}
  51.     byhost = {}
  52.     byuser = {}
  53.     bytype = {}
  54.     lineno = 0
  55.     try:
  56.         while 1:
  57.             line = f.readline()
  58.             if not line: break
  59.             lineno = lineno + 1
  60.             if search and string.find(line, search) < 0:
  61.                 continue
  62.             if prog.match(line) < 0:
  63.                 print 'Bad line', lineno, ':', `line`
  64.                 continue
  65.             items = prog.group(1, 2, 3, 4, 5, 6)
  66.             (logtime, loguser, loghost, logfile, logbytes,
  67.              logxxx2) = items
  68. ##             print logtime
  69. ##             print '-->', loguser
  70. ##             print '--> -->', loghost
  71. ##             print '--> --> -->', logfile
  72. ##             print '--> --> --> -->', logbytes
  73. ##             print '--> --> --> --> -->', logxxx2
  74. ##             for i in logtime, loghost, logbytes, logxxx2:
  75. ##                 if '!' in i: print '???', i
  76.             add(bydate, logtime[-4:] + ' ' + logtime[:6], items)
  77.             add(bytime, logtime[7:9] + ':00-59', items)
  78.             direction, logfile = logfile[0], logfile[1:]
  79.             # The real path probably starts at the last //...
  80.             while 1:
  81.                 i = string.find(logfile, '//')
  82.                 if i < 0: break
  83.                 logfile = logfile[i+1:]
  84.             add(byfile, logfile + ' ' + direction, items)
  85.             logdir = os.path.dirname(logfile)
  86. ##        logdir = os.path.normpath(logdir) + '/.'
  87.             while 1:
  88.                 add(bydir, logdir + ' ' + direction, items)
  89.                 dirhead = os.path.dirname(logdir)
  90.                 if dirhead == logdir: break
  91.                 logdir = dirhead
  92.             add(byhost, loghost, items)
  93.             add(byuser, loguser, items)
  94.             add(bytype, direction, items)
  95.     except KeyboardInterrupt:
  96.         print 'Interrupted at line', lineno
  97.     show(bytype, 'by transfer direction', maxitems)
  98.     show(bydir, 'by directory', maxitems)
  99.     show(byfile, 'by file', maxitems)
  100.     show(byhost, 'by host', maxitems)
  101.     show(byuser, 'by user', maxitems)
  102.     showbar(bydate, 'by date')
  103.     showbar(bytime, 'by time of day')
  104.  
  105. def showbar(dict, title):
  106.     n = len(title)
  107.     print '='*((70-n)/2), title, '='*((71-n)/2)
  108.     list = []
  109.     keys = dict.keys()
  110.     keys.sort()
  111.     for key in keys:
  112.         n = len(str(key))
  113.         list.append((len(dict[key]), key))
  114.     maxkeylength = 0
  115.     maxcount = 0
  116.     for count, key in list:
  117.         maxkeylength = max(maxkeylength, len(key))
  118.         maxcount = max(maxcount, count)
  119.     maxbarlength = 72 - maxkeylength - 7
  120.     for count, key in list:
  121.         barlength = int(round(maxbarlength*float(count)/maxcount))
  122.         bar = '*'*barlength
  123.         print '%5d %-*s %s' % (count, maxkeylength, key, bar)
  124.  
  125. def show(dict, title, maxitems):
  126.     if len(dict) > maxitems:
  127.         title = title + ' (first %d)'%maxitems
  128.     n = len(title)
  129.     print '='*((70-n)/2), title, '='*((71-n)/2)
  130.     list = []
  131.     keys = dict.keys()
  132.     for key in keys:
  133.         list.append((-len(dict[key]), key))
  134.     list.sort()
  135.     for count, key in list[:maxitems]:
  136.         print '%5d %s' % (-count, key)
  137.  
  138. def add(dict, key, item):
  139.     if dict.has_key(key):
  140.         dict[key].append(item)
  141.     else:
  142.         dict[key] = [item]
  143.  
  144. main()
  145.